<?php

namespace addons\csmitsm\library\xcore\xcflow\base;

use addons\csmitsm\library\sdnode\xstack\utils\XsJsonUtils;
use addons\csmitsm\library\xcore\xcflow\utils\XcflowallformUtils;
use addons\csmitsm\library\xcore\xcore\base\XcAAdminApi;
use addons\csmitsm\library\xcore\xcore\utils\XcDaoUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcRequestUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcDatabaseUtils;
use addons\csmitsm\library\xcore\xcflow\utils\XcformFieldsUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcTransactionUtils;

abstract class XcformAAddonsController extends XcAAdminApi
{
    protected $xcformDao = null;
    protected $xcformFieldDao = null;
    protected $xcformidFieldname = null;
    protected $staticFieldsJsonString = null;


    private function _getFormgenerateFields($xcform_id)
    {
        $fieldList = XcDaoUtils::getListBySql($this->xcformFieldDao, [
            [$this->xcformidFieldname, "=", $xcform_id]
        ], null, "weigh asc ");

        $fields = [];
        if (count($fieldList) > 0) {
            foreach ($fieldList as $item) {
                // $fieldjsonObj =  empty($item->fieldjson) ? [] : json_decode($item->fieldjson, true);
                $fieldjsonObj = XsJsonUtils::stringToJson($item->fieldjson);
                if (isset($fieldjsonObj['xcform_base_inputfieldcode'])) {
                    $fieldjsonObj['xcform_base_inputfieldcode']['haspublish'] = $item->haspublish;
                    $fieldjsonObj['xcform_base_inputfieldcode']['publishtype'] = $item->publishtype;
                }
                $fieldjsonObj['id'] = $item->id;
                $fields[] = $fieldjsonObj;
            }
        } 
        return $fields;
    }

    public function getXcFormFields()
    {
        $xcform_id = XcRequestUtils::get("xcform_id", true);
        $fields = $this->_getFormgenerateFields($xcform_id);
        $xcform = XcDaoUtils::getRowById($this->xcformDao, $xcform_id);

        $rr = $this->_getXcFormFields();
        if ($rr === true) {
            $this->success(null, [
                'fields' => $fields,
                'displayfieldcode' => $xcform->displayfieldcode,
                "needPublish" => XcformFieldsUtils::needPublish($this->xcformFieldDao, $this->xcformidFieldname, $xcform_id),
            ]);
        }
    }

    protected function _getXcFormFields()
    {
        return true;
    }



    public function saveXcFormFields()
    {
        $xcform_id = XcRequestUtils::get("xcform_id", true);
        $fieldsjson = XcRequestUtils::requestBodyJson();

        $result = XcTransactionUtils::service(function () use ($xcform_id, $fieldsjson) {
            // 将 xcform_base_defaultvalue 中的 field__vModel__ 改为 fieldcode (因为仅在发布时 fieldcode 才不会改变)
            if(true){
                foreach($fieldsjson as &$field){
                    if(isset($field['xcform_base_defaultvalue']['type'])&&$field['xcform_base_defaultvalue']['type']=='objselect_field'){
                        $vModel = $field['xcform_base_defaultvalue']['objselect_field']['field__vModel__'];
                        foreach($fieldsjson as $field2){
                            if($field2["__vModel__"]==$vModel){
                                $field['xcform_base_defaultvalue']['objselect_field']['fieldcode'] = $field2['xcform_base_inputfieldcode']['value'];
                                break;
                            }
                        }
                    }
                }
            }


            // createOrUpdate xcformfield_table
            $vmodels = [];
            if (true) {
                // $weighcount = count($fieldsjson);
                foreach ($fieldsjson as $index => $item) {
                    $vmodel = $item['__vModel__'];
                    $fieldcode = isset($item['xcform_base_inputfieldcode']['value']) ? $item['xcform_base_inputfieldcode']['value'] : "";

                    $row = XcDaoUtils::getRowBySql($this->xcformFieldDao, [
                        [$this->xcformidFieldname, '=', $xcform_id],
                        ['vmodel', '=', $vmodel]
                    ]);
                    $pp = [
                        $this->xcformidFieldname => $xcform_id,
                        'title' => isset($item['xcform_base_xctitle']['value']) ? $item['xcform_base_xctitle']['value'] : null,
                        'fieldcode' => $fieldcode,
                        'fieldtag' => $item['__config__']['tag'],
                        'weigh' => $index,
                        'fieldjson' => XsJsonUtils::jsonToString($item),
                    ];
                    if ($row) {
                        $pp['publishtype'] = ($row['haspublish'] == "Y") ? 'change_column' : $row['publishtype'];
                        $pp['haspublish'] = 'N';
                        $row->save($pp);
                    } else {
                        $pp['publishtype'] = "add_column";
                        $pp['haspublish'] = 'N';
                        $pp['vmodel'] = $vmodel;
                        $row = $this->xcformFieldDao->create($pp);
                    }
                    $vmodels[] = $vmodel;
                }
            }
            // drop column from xcformfield_table
            if (true) {
                // var_dump($fieldIds);
                $list = XcDaoUtils::getListBySql($this->xcformFieldDao, [
                    [$this->xcformidFieldname, '=', $xcform_id],
                    ['vmodel', 'not in', $vmodels]
                ]);
                foreach ($list as $item) {
                    // echo "D-".$item->id;
                    XcDaoUtils::getRowById($this->xcformFieldDao, $item->id)->save([
                        'status' => 'hidden',
                        'haspublish' => 'N',
                        'publishtype' => 'drop_column',
                    ]);
                }
            }
            // override method      
            return $this->_getXcFormFields();
        });


        if ($result === true) {
            $this->success(null, [
                "needPublish" => XcformFieldsUtils::needPublish($this->xcformFieldDao, $this->xcformidFieldname, $xcform_id),
            ]);
        }
    }

    protected function _saveXcFormFields()
    {
        return true;
    }

    protected abstract function _publishXcForm_alertColumn($xcform, $field, $fieldcode, $columnType, $fieldTitle);




    public function publishXcForm()
    {
        $xcform_id = XcRequestUtils::get("xcform_id", true);
        $displayfieldcode = XcRequestUtils::post("displayfieldcode");

        $result = XcTransactionUtils::service(function () use ($xcform_id, $displayfieldcode) {
            // init
            $xcform = XcDaoUtils::getRowById($this->xcformDao, $xcform_id);

            // add_column&change_column
            if (true) {
                $fieldList = XcDaoUtils::getListBySql($this->xcformFieldDao, [
                    [$this->xcformidFieldname, "=", $xcform_id]
                ]);

                // assert unique fieldcode
                if (true) {
                    $fieldcodes = [];
                    foreach ($fieldList as $field) {
                        $fieldcode = $field->fieldcode;
                        if (!empty($fieldcode) && in_array($fieldcode, $fieldcodes)) {
                            $this->error("字段编码重复:" . $fieldcode);
                        }
                        $fieldcodes[] = $fieldcode;
                    }
                }

                $tablename = $xcform->publishtablename;
                foreach ($fieldList as $field) {
                    $fieldInstance = XcformFieldsUtils::createFieldInstance("xcform", $field);
                    $fieldInstance->assertXcfieldjson();
                    $fieldcode = $field['fieldcode'];
                    $fieldTitle = $field['title'];
                    $columnType = $fieldInstance->getDbfieldColumnType();

                    // alert column to db_table , update xcformfield_table haspublish=Y
                    if ($field->haspublish == 'N') {
                        $publishfieldcode = XcDatabaseUtils::alertTableField($field->publishtype, $tablename, $fieldcode, $columnType, $fieldTitle);
                        $this->_publishXcForm_alertColumn($xcform, $field, $fieldcode, $columnType, $fieldTitle);
                        $field->save(['haspublish' => 'Y', 'publishfieldcode' => $publishfieldcode]);
                    }

                    // update xcform_table's xcfieldjson_column
                    if (true) {
                        $xcflowfield = [];

                        $fieldList = XcDaoUtils::getListBySql($this->xcformFieldDao, [
                            [$this->xcformidFieldname, "=", $xcform_id]
                        ], null, "weigh asc");
                        foreach ($fieldList as $item) {
                            $xcflowfield[] = [
                                'title' => $item->title,
                                'fieldjson' => $item->fieldjson,
                                'fieldcode' => $item->fieldcode,
                                'fieldtag' => $item->fieldtag,
                            ];
                        }
                        $xcform = XcDaoUtils::getRowById($this->xcformDao, $xcform_id);
                        $xcform->save([
                            'xcfieldjson' => XsJsonUtils::jsonToString($xcflowfield),
                            'displayfieldcode' => $displayfieldcode,
                            'updatetime' => time(),
                        ]);
                    }
                }
                $xcform->save(['haspublish' => 'Y']);
            }

            // drop_column
            if (true) {
                $fieldList = XcDaoUtils::getListBySql($this->xcformFieldDao, [
                    [$this->xcformidFieldname, "=", $xcform_id],
                    ['status', '=', 'hidden'],
                    ['publishfieldcode', 'not null']
                ], null, null, false);
                foreach ($fieldList as $field) {
                    $fieldInstance = XcformFieldsUtils::createFieldInstance("xcform", $field);
                    $fieldInstance->assertXcfieldjson();
                    $fieldcode = $field['fieldcode'];
                    $fieldTitle = $field['title'];
                    $columnType = $fieldInstance->getDbfieldColumnType();

                    // alert column to db_table , update xcformfield_table haspublish=Y
                    if ($field->haspublish == 'N') {
                        $publishfieldcode = XcDatabaseUtils::alertTableField($field->publishtype, $tablename, $fieldcode, $columnType, $fieldTitle);
                        $this->_publishXcForm_alertColumn($xcform, $field, $fieldcode, $columnType, $fieldTitle);
                        $field->save(['haspublish' => 'Y', 'publishfieldcode' => $publishfieldcode]);
                    }
                }
            }


            return $this->_publishXcForm();
        });
        $fields = $this->_getFormgenerateFields($xcform_id);
        if ($result === true) {
            $this->success(null, ['fields' => $fields,]);
        }
    }

    protected function _publishXcForm()
    {
        return true;
    }

    public function queryDataTables()
    {
        $list = XcflowallformUtils::queryTableinfoList([["xcformtype", "in", ['flow', 'flowsub', 'mdm']]]);
        $this->success(null, ["list" => $list]);
    }

    public function queryFieldsByTableName()
    {
        $tablename = XcRequestUtils::get("tablename");
        $list = XcDatabaseUtils::queryTablefieldList($tablename);
        $this->success(null, ["list" => $list]);
    }

    public function queryTabledataList()
    {
        $pageNumber = XcRequestUtils::get("pageNumber");

        $tablename = XcRequestUtils::get("tablename");
        $showfields = XcRequestUtils::get("showfields");
        $filterfields = XcRequestUtils::get("filterfields");
        $filtervalue = XcRequestUtils::get("filtervalue");

        $result = XcDatabaseUtils::queryTabledataList($tablename, $showfields, $filterfields, $filtervalue, $pageNumber, 6);
        $this->success(null, $result);
    }
}
